home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-10-08 | 22.8 KB | 968 lines | [TEXT/MSET] |
- \ Standard data structure classes
-
- \ May 91 Added Longword
- \ June 91 Reimplemented ordered-col etc. using multiple inheritance
- \ May 92 Added obj-array
- \ July 92 Fixed OBJ: ObjHandle to use NPTR: instead of PTR:
- \ HandleArray now inherits from Obj_array.
- \ Dec 92 Replaced UGET: in Int and Byte with new classes UINT and UBYTE.
-
-
- :class LONGWORD super{ object } \ Generic superclass for var, handle etc.
-
- 4 bytes data
-
- :m CLEAR: inline{ 0 obj !} 0 ^base ! ;m
- :m GET: inline{ obj @} ^base @ ;m
- :m PUT: inline{ obj !} ^base ! ;m
- :m ->: inline{ @ obj !} chksame @ put: self ;m
-
- :m PRINT: ^base @ . ;m
-
- :m CLASSINIT: clear: self ;m
-
- ;class
-
-
- :class VAR super{ longword }
-
- :m +: inline{ obj +!} ^base +! ;m
- :m -: inline{ obj -!} ^base -! ;m
- ;class
-
-
- :class INT super{ object }
-
- 2 bytes data
-
- :m CLEAR: inline{ 0 obj w!} 0 ^base w! ;m
- :m GET: inline{ obj w@x} ^base w@x ;m
- :m PUT: inline{ obj w!} ^base w! ;m
- :m +: inline{ obj w+!} ^base w+! ;m
- :m -: inline{ obj w-!} ^base w-! ;m
- :m ->: inline{ w@ obj w!}
- chksame w@ put: self ;m
-
- :m INT: ^base w@ makeint ;m \ return as toolbox int
-
- :m PRINT: ^base w@ . ;m
-
- :m CLASSINIT: clear: self ;m
-
- ;class
-
- :class UINT super{ int }
-
- :m GET: inline{ obj w@} ^base w@ ;m
-
- ;class
-
-
- :class BYTE super{ object }
-
- 1 bytes data
-
- :m CLEAR: inline{ 0 obj c!} 0 ^base c! ;m
- :m GET: inline{ obj c@x} ^base c@x ;m
- :m PUT: inline{ obj c!} ^base c! ;m
- :m ->: inline{ c@ obj c!} chksame c@ put: self ;m
-
- :m PRINT: ^base c@ . ;m
-
- :m CLASSINIT: clear: self ;m
-
- ;class
-
-
- :class UBYTE super{ byte }
-
- :m GET: inline{ obj c@} ^base c@ ;m
-
- ;class
-
-
- :class BOOL super{ byte }
-
- :m PUT: inline{ 0<> obj c!} 0<> ^base c! ;m
- :m SET: inline{ true obj c!} true ^base c! ;m
-
- :m PRINT: get: self IF ." true" ELSE ." false" THEN ;m
-
- ;class
-
-
- \ Handle class can store handles to relocatable heap blocks.
- \ It would be nice to store the length too, but this class is used
- \ for handles in toolbox records so we can't. Not here at least.
-
- 0 value RELCNT \ For testing - counts release: msgs
- \ to make sure we're releasing everything
-
- :class HANDLE super{ longword }
-
- :m PTR: \ Dereferences handle to get pointer. Trap if nil.
- inline{ obj @ @} ^base @ @ ;m
-
- :m NPTR: \ Dereferences handle and masks with SAmask so we can
- \ use the pointer numerically.
- ^base @ @ SAmask and ;m
-
- :m RELEASE: \ Deallocates the heap block, if allocated.
- 1 ++> relCnt killH ;m
-
- :m CLEAR: nilH ^base ! ;m \ We hope we know what we're doing.
-
- :m NIL?: \ ( -- b )
- get: self nilH = ;m
-
- :m SETSIZE: \ ( size -- }
- setHsz 0= ?error 166 ;m
-
- :m SIZE: \ ( -- size ) Gets current size.
- getHSz ;m
-
- :m NEW: \ ( size -- )
- newH 0= ?error 166 ;m
-
- :m LOCK: lok ;m
- :m UNLOCK: unlok ;m
-
- :m GETSTATE: ( -- state ) HgetSt ;m
- :m SETSTATE: ( state -- ) HsetSt ;m
-
- :m LOCKED?: ( -- b ) HgetSt $ 80 and 0<> ;m
-
- :m MOVEHI: MvHHi drop ( errors don't really matter here ) ;m
-
- :m ->: \ ( ^hdl -- ) Copies passed-in handle's heap data to self.
- chkSame copyH ?error 167 ;m
-
- :m PRINT:
- & $ emit ^base @ u.h ;m \ We assume a print: of a handle is more
- \ useful in hex.
-
- :m CLASSINIT: clear: self ;m \ Initially nil
-
- ;class
-
-
- \ OBJHANDLE is a handle that points to an object in the heap.
-
- :class OBJHANDLE super{ handle }
-
- :m OBJ: moveHi: self lock: self nptr: self >obj ;m
-
- \ Note: if we're going to bind to a heap-based object,
- \ the handle MUST be locked while we do so - anything
- \ may happen before the method returns!! Thus we make the
- \ obj: method do a moveHi and lock. But remember to unlock
- \ the handle eventually! (Unless you're releasing it, of course.)
-
- :m NEWOBJ: ( #els ) { ^class -- }
- \ Usage: 5 ['] someClass newObj: someHndl
-
- ^class cl>len 8 + new: self
- ^class obj: self make_obj unlock: self ;m
-
- :m RELEASEOBJ:
- nil?: self ?EXIT
- obj: self release: [] release: super ;m
-
- :m RELEASE: releaseObj: self ;m \ Standard destructor name.
-
- \ Note: we define both release: and releaseObj: so that in classes
- \ HandleArray and HandleList we can distinguish between releasing the
- \ current object and releasing the whole lot. Release: is of course
- \ overridden in those two classes to release the entire structure.
-
- :m PRINT:
- print: super 4 spaces ." object: "
- nil?: self
- if ." (none)"
- else print: [ obj: self ] unlock: self
- then ;m
-
- :m DUMP:
- dump: super cr
- ." object: "
- nil?: self
- if ." (none)"
- else dump: [ obj: self ] unlock: self
- then ;m
-
- ;class
-
- :class PTR super{ longword }
-
- :m RELEASE: \ Deallocates the heap block, if allocated.
- killP ;m
-
- :m NEW: ( len -- ) newP 0= ?error 121 ;m
-
- :m NIL?: ( -- b ) ^base @ nilP = ;m
-
- :m CLEAR: nilP ^base ! ;m \ We hope we know what we're doing.
-
- :m CLASSINIT: clear: self ;m \ Initially nil
-
- ;class
-
-
- \ DICADDR is a relocatable dictionary address class - use to store
- \ non-executable dictionary addresses.
-
- :class DICADDR super{ longword }
-
- :m GET: ^base @abs ;m
- :m PUT: ^base reloc! ;m
-
- :m PRINT: get: self .id ;m
-
- :m CLASSINIT: ['] null put: self ;m
-
- ;class
-
-
- \ X-ADDR is an executable dictionary address class. The only significant
- \ difference to DicAddr is that there is an Exec: method.
- \ But if we ever have to separate code and data, having a separate class
- \ could prove very useful. An x-addr is the same as a Mops execution token.
-
- :class X-ADDR super{ object }
-
- 4 bytes data
-
- :m EXEC: inline{ obj ex} ^base @abs execute ;m
-
- :m GET: ^base @abs ;m
- :m PUT: ^base reloc! ;m
-
- :m CLASSINIT: ['] null put: self ;m
-
- ;class
-
-
- \ ============= Arrays ===============
-
- : ?#XTS \ ( n1 n2 -- ) Used to check that the right
- \ number of stacked cfas is being passed in.
- <> ?error 171 ; \ "Wrong number of cfas"
-
-
- \ Class INDEXED-OBJ is the generic superclass for all arrays. Here we define
- \ the general indexed methods, which apply regardless of indexed width.
-
- :class INDEXED-OBJ super{ object }
-
- :m ^ELEM: ^elem ;m
-
- :m LIMIT: limit ;m
-
- :m WIDTH: idxbase 6 - w@ ;m
-
- :m IXADDR: idxbase ;m
-
- :m CLEARX: \ Erases indexed area.
- idxbase limit width: self * erase ;m
-
- ;class
-
-
- \ ARRAY is the basic 4-byte cell array.
-
- :class ARRAY super{ indexed-obj } 4 indexed
-
- :m AT: ( index -- n ) inline{ ix @} ^elem4 @ ;m
- :m TO: ( n index -- ) inline{ ix !} ^elem4 ! ;m
- :m +TO: ( n index -- ) inline{ ix +!} ^elem4 +! ;m
- :m -TO: ( n index -- ) inline{ ix -!} ^elem4 -! ;m
- :m ^ELEM: ( idx -- addr ) inline{ ix} ^elem4 ;m
-
- :m FILL: \ ( value -- ) Fills all elements with value.
- idxbase limit 4* bounds
- ?do dup i ! 4 +loop drop ;m
-
- :m WIDTH: 4 ;m \ Faster than the default in Indexed-obj.
-
- :m GETELEM: \ ( addr -- n ) Fetches one element at addr - saves indexing
- \ step if addr is known.
- @ ;m
-
- ;class
-
-
- \ X-ARRAY can execute its elements.
-
- :class X-ARRAY super{ array }
-
- :m TO: ( index -- ) ^elem: super reloc! ;m
-
- :m EXEC: ( index -- )
- inline{ ix ex} ^elem: self @abs execute ;m
-
- :m FILL: \ ( xt -- )
- limit nif drop exit then \ Out if no elements
- idxbase tuck reloc! @ fill: super ;m
-
- :m PUT: \ ( xt0 ... xt(N-1) N -- )
- limit 0EXIT \ Out if no elements
- false -> relocChk? \ May get used in instantiating exported objs
- limit ?#xts
- idxbase dup limit 1- 4* +
- do i reloc! -4 +loop
- true -> relocChk? ;m
-
- :m ACTIONS: \ A synonym for put:. A more appropriate name to use in
- \ sub-classes such as dialogs.
- put: self ;m
-
- private
-
- :m PrintNxts: \ ( n -- )
- 0 ?do i ^elem: self @abs cr .id loop ;m
-
- public
-
- :m PRINT: limit printNxts: self ;m
-
- :m CLASSINIT: ['] null fill: self ;m
-
- ;class
-
-
- \ SEQUENCE is a generic superclass for classes which have multiple items which
- \ frequently need to be looked at in sequence. At present the main function of
- \ Sequence is to implement the EACH: method, which makes it very simple to
- \ deal with each element. The usage is
- \
- \ BEGIN each: <obj> WHILE <do something to the element> REPEAT
- \
- \ Sequence can be multiply inherited with any class which implements the
- \ FIRST?: and NEXT?: methods. The actual implementation details are quite
- \ irrelevant, as long as these methods are supported.
-
- \ But note that any class using Sequence should not appear in a record, since
- \ we must late bind to self, so a class pointer must be present.
-
- :class SEQUENCE super{ object } general
-
- record
- { var NXT_XT
- var ^SELF
- }
-
- :m EACH: \ ( -- (varies) T | -- F )
- get: nxt_xt
- NIF \ First time in:
- first?: [self] 0dup 0EXIT
- self bind_with next?: \ Late-bind to next?: and cache
- put: nxt_xt put: ^self \ the xt for the loop
- true \ Yes, we've got the 1st element
- ELSE \ Subsequent time in:
- get: ^self get: nxt_xt ex-method \ Call next?: method (cached)
- IF true ELSE clear: nxt_xt false THEN
- THEN ;m
-
- :m UNEACH: \ Use to terminate an EACH: loop before the end.
- clear: nxt_xt ;m
-
- ;class
-
-
- 0 value LASTSUP
- 0 value LASTSUPADDR
-
- : REMOVELASTSUPER { ^class \ infa -- }
- ^class ifa displace -> infa
- BEGIN infa @ 0> NWHILE infa ^nextivar -> infa
- REPEAT
- BEGIN
- 4 ++> infa
- infa @
- NUNTIL
- 4 --> infa
- infa -> lastSupAddr
- infa @ -> lastSup
- 0 infa ! ;
-
- : RESTORELASTSUPER
- lastSup lastSupAddr ! ;
-
-
- \ OBJ_ARRAY is a generic superclass which makes it easy to generate an array
- \ of objects of a given class. Just define a new class which multiply
- \ inherits from the given class (or classes) and OBJ_ARRAY (which must come
- \ last). This will add an indexed section to each object of the new class,
- \ with elements wide enough to contain objects of the original class. Then
- \ SELECT: "switches in" the selected element to be the "current" element,
- \ and all the normal methods of the class can then be used.
- \ The implementation is general rather than brilliantly fast. If switching
- \ between elements is really a performance concern, you could override
- \ SELECT: - especially if you know the element width. But note, we do
- \ assume the elements are aligned.
-
- :class OBJ_ARRAY super{ indexed-obj sequence } 32767 indexed
- \ The 32767 signals that the real indexed width is to be
- \ taken from the other superclass(es).
-
- record{ int CURRENT }
-
- :m CURRENT:
- get: current ;m
-
- :m SELECT: { idx \ datalen slf -- }
- idx get: current = ?EXIT \ out if nothing to do
- width: self -> datalen self -> slf \ set up
- slf get: current ^elem datalen aligned_move \ switch out previous
- idx put: current
- idx ^elem slf datalen aligned_move ;m \ switch in new
-
- :m FIRST?:
- limit NIF false EXIT THEN
- 0 select: self true ;m
-
- :m NEXT?:
- get: current 1+ limit >= IF false EXIT THEN
- get: current 1+ select: self true ;m
-
-
- :m PRINTALL: \ Sends PRINT: to all elements
- get: current
- BEGIN each: self WHILE print: [self] REPEAT
- select: self ;m
-
- (*
- We need to initialize all the elements. Element 0 has been initialized
- already, by the time we get classinit: sent here, since we're the last
- superclass. We could select each element and send deep_classinit:, but
- it's a bit tricky getting the right class to use. Instead we'll just
- copy element 0 to the other elements, which will usually be good enough.
- *)
-
- :m CLASSINIT: { \ dln slf -- }
- width: self -> dln self -> slf \ set up
- limit 1 \ note: elt 0 has had classinit: already!
- ?DO
- slf i ^elem dln aligned_move
- LOOP
- ;m
-
- ;class
-
-
- \ (PHlist) is a superclass for HandleList and PtrList, mainly aimed at
- \ factoring out common code. It's really only meant for internal use.
-
- :class (PHlist) super{ sequence }
-
- record
- { handle THELIST
- var SIZE
- var POS
- }
-
- private
-
- :m (SEL): \ ( n -- ) n is offset into theList, NOT an index.
- self @ ptr: theList get: pos + ! \ switch out previous
- put: pos
- ptr: theList get: pos + @ self ! \ switch in new
- ;m
-
- public
-
- :m ADD: { addMe \ whr ^class -- }
- get: size -> whr
- whr
- NIF nil?: theList
- IF 80 new: theList \ Give it room to play with
- ELSE 80 setsize: theList
- THEN
- THEN
- whr cell+ dup setsize: theList put: size
- whr (sel): self
- addMe self !
- ;m
-
-
- :m REMOVE: { \ whr cnt -- } \ Completely removes the current element.
- ptr: theList get: pos + -> whr
- 1cell -: size get: size get: pos - -> cnt
- cnt IF whr cell+ whr cnt move THEN
- \ note: can't use aligned_move since it's a move down,
- \ and overlaps
- get: pos cell- 0 max put: pos
- ptr: theList get: pos +
- ptr: theList get: pos + @ self ! \ switch in new current elt
- get: size NIF release: theList THEN ;m
-
-
- :m SELECT: \ ( n -- )
- 4* 0 get: size cell- within? not ?error 134
- (sel): self ;m
-
- :m SELECTLAST:
- get: size cell- (sel): self ;m
-
- :m CURRENT: get: pos 4/ ;m
-
- :m SIZE: get: size 4/ ;m
-
- \ The next two methods are needed by EACH:, but may be called directly as well.
- \ Note that NEXT?: ASSUMES that the list is allocated in the heap and that a
- \ valid element is selected as the current element. EACH: ensures this,
- \ since if FIRST?: returns false, NEXT?: is never called. But if you call
- \ it directly, make sure this condition holds.
-
- :m FIRST?: \ ( -- n T | -- F )
- nil?: theList IF false EXIT THEN
- 0 (sel): self self @ true ;m
-
- :m NEXT?: { \ nxt -- n T | -- F }
- get: pos cell+ -> nxt
- nxt get: size >= IF false EXIT THEN
- nxt (sel): self self @ true ;m
-
-
- :m DUMPALL:
- nil?: theList IF ." (not open)" EXIT THEN
- dump: super cr ." current: " current: self dup .
- cr ." elements: " cr
- BEGIN each: [self] WHILE dump: [self] REPEAT
- select: self ;m
-
- :m PRINTALL:
- nil?: theList IF ." (not open)" EXIT THEN
- get: pos
- BEGIN each: self WHILE print: [self] cr REPEAT
- (sel): self ;m
-
- ;class
-
-
- \ HANDLEARRAY and HANDLELIST are for the implementation of collections
- \ of heap-based objects. HandleArray has normal array properties, and
- \ thus a definite length. HandleList, however, allows the number of
- \ elements to grow arbitrarily large. Use HandleList if you need an
- \ indefinite number of elements, and if indexing isn't so important.
- \ HandleArray also includes methods to allow the array to be used as a
- \ stack - needed for FileList.
-
- :class HANDLEARRAY super{ objHandle array obj_array }
-
- record
- { int size }
-
- :m SIZE: get: size ;m
- :m SETSIZE: put: size ;m
-
- :m RELEASE:
- get: size 0 ?DO
- i select: self releaseObj: self
- LOOP ;m
-
- :m PUSH: \ ( hdl -- )
- get: size limit >= ?error 137
- get: size select: self 1 +: size
- put: super ;m
-
- private
- :m (TOP):
- get: size dup
- IF 1- select: self
- ELSE drop clear: current
- THEN ;m
- public
-
- :m TOP:
- get: size 0= ?error 136 (top): self ;m
-
- :m DROP:
- get: size dup 0= ?error 136
- 1- select: self releaseObj: self
- 1 -: size (top): self ;m
-
- :m PUSHNEWOBJ:
- 0 push: self newObj: self ;m
-
- :m CLEARX: nilH fill: self ;m
-
- :m CLASSINIT: clearX: self clear: self ;m
-
- ;class
-
-
- \ HANDLELIST allows the implementation of a list of heap-based objects.
- \ Unlike HANDLEARRAY, the list can be of indefinite length. We use a heap
- \ block to store the handles to the objects contiguously, rather than have
- \ a separate block for each handle and link them together. This saves on
- \ memory overhead and reduces the number of memory manager calls. It also
- \ reflects the assumption that insertions and deletions into the middle of
- \ the list will be infrequent, as these could be more inefficient than with
- \ a linked scheme. We expect that elements will normally be added to the
- \ end, and probably not removed at all, or not very often.
-
-
- :class HANDLELIST super{ objHandle (PHlist) }
-
- \ FIRST?: and NEXT?:, needed for the EACH: construction, are overridden here
- \ since if the next element exists we return the object address as well as
- \ the True. We also need to unlock the previous objHandle when we step
- \ to the next one.
-
- :m SIZE: \ We're overriding here since objHandle has a size: method
- \ which isn't really useful here
- size: super> (PHlist) ;m
-
- :m FIRST?: \ ( -- ^obj T | -- F )
- first?: super NIF false EXIT THEN
- drop obj: self true ;m
-
- :m NEXT?: { \ nxt -- ^obj T | -- F }
- unlock: super
- next?: super NIF false EXIT THEN
- drop obj: self true ;m
-
-
- :m NEWOBJ: \ ( ^class -- )
- nilH add: super> (PHlist)
- newObj: super ;m
-
- :m REMOVEOBJ: \ Completely removes the current element.
- releaseObj: super remove: super ;m
-
- :m RELEASE:
- BEGIN each: self WHILE drop releaseObj: super REPEAT
- release: theList
- clear: pos clear: size ;m
-
- :m DUMPALL:
- nil?: theList if ." (not open)" EXIT THEN
- dump: super cr ." current: " get: pos dup 4/ .
- cr ." elements: " cr
- BEGIN each: self WHILE dump: [] REPEAT
- (sel): self ;m
-
- :m PRINTALL:
- nil?: theList if ." (not open)" EXIT THEN
- get: pos
- BEGIN each: self WHILE print: [] cr REPEAT
- (sel): self ;m
-
- ;class
-
-
- :class PTRLIST super{ ptr (PHlist) }
-
- ;class
-
-
- \ ============== Collections ================
-
- \ Collections are ordered lists with a current size. We implement them by
- \ multiply inheriting the generic (COL) class with the array class of the
- \ appropriate width. We use a few tricks to avoid late binding to self
- \ in loops.
-
- :class (COL) super{ object }
-
- record
- { int SIZE } \ # elements in list
-
- :m SIZE: \ ( -- cursize ) Returns #elements currently in list
- inline{ get: size} get: size ;m
-
- :m CLEAR: \ Set to list to null
- clear: size clearx: [self] ;m
-
- :m ADD: \ ( val -- ) add value to end of list
- get: size limit >= ?error 137
- get: size to: [self] 1 +: size ;m
-
- :m LAST: \ ( -- val ) Returns contents of end of list
- get: size dup 0= ?error 136
- 1- at: [self] ;m
-
- :m REMOVE: { indx \ cnt wid addr -- } \ Removes the element at index
- get: size indx - 1- -> cnt
- cnt 0< ?error 136
- width: [self] -> wid
- indx ^elem: [self] -> addr
- 1 -: size
- cnt 0exit
- addr wid + addr cnt wid * move ;m
-
- :m INDEXOF: { val \ ^self ^getelem wid addr -- indx T | -- F }
- \ Finds a value in a collection.
- self bind_with getelem: -> ^getelem -> ^self
- width: [self] -> wid idxbase -> addr
- false get: size 0
- ?do
- addr ^self ^getelem ex-method
- val = if drop i true leave then
- wid ++> addr
- loop ;m
-
- :m PRINT:
- get: size 0 ?do i at: [self] cr . loop ;m
-
- :m DUMP:
- dump: super ." size: " get: size . ;m
-
- ;class
-
-
- \ Ordered-Collection is a collection of 4-byte cells.
-
- :class ORDERED-COL super{ (col) array }
- ;class \ That's all, folks!!
-
-
- \ X-COL is a collection of execution tokens.
-
- :class X-COL super{ (col) x-array }
-
- :m REMOVEXT: \ ( xt -- )
- false -> relocChk? pad reloc! true -> relocChk?
- pad @ indexof: self 0EXIT
- remove: self ;m
-
- :m PRINT:
- get: size printNXts: self ;m
-
- ;class
-
-
-
-
- :class DIC-MARK super{ object }
-
- #threads array LINKS
- record { int CURRENT }
-
- private
-
- :m SETC: { \ addr index -- index }
- 0 -> addr 0 -> index
- #threads FOR
- i at: links dup addr u>
- IF -> addr i -> index ELSE drop THEN
- NEXT
- index put: current ;m
- public
-
- :m CURRENT:
- get: current at: links ;m
-
- :m SET: { addr -- }
- #threads FOR
- context i 2 << + displace
- BEGIN dup addr u> \ We're 32-bit clean around here!
- WHILE displace
- REPEAT
- i to: links
- NEXT
- setc: self ;m
-
- :m SETTOTOP: big# set: self ;m
-
- :m NEXT: { \ lfa -- lfa }
- get: current at: links
- dup -> lfa dup 0EXIT
- displace get: current to: links
- setc: self lfa ;m
-
- ;class
-
- dic-mark TheMARK
-
-
- \ ========== Resource support ===========
-
- :class RESOURCE super{ handle }
-
- record
- { var RESTYPE
- int ID
- }
-
- :m SET: \ ( type id# -- )
- put: ID put: resType ;m
-
- :m GETNEW:
- get: resType get: ID getRes dup
- NIF \ Failed - display type and ID
- cr addr: resType 4 type 2 spaces
- get: ID . 170 die \ Couldn't find this resource
- THEN
- put: super ;m
-
- :m GETXSTR: { idx \ addr -- addr len }
- getnew: self
- ptr: self -> addr
- addr w@ 1- idx min -> idx
- 2 ++> addr
- idx 0 ?DO addr count + -> addr LOOP
- addr count ;m
-
- ;class
-
- \ ====================================
-
- \ SOME UTILITY WORDS
-
- \ ====================================
-
- \ Any special run-time initialization can be done conveniently by adding
- \ the appropriate words to the x-col INIT_ACTIONS. These words will be
- \ executed on startup via EXTRA_INITS, right after OBJINIT.
-
- 8 x-col INIT_ACTIONS
-
- : X size: init_actions 0 ?DO i exec: init_actions LOOP ;
-
- ' x -> extra_inits
-
-
- : SCREENBITS \ ( -- l t r b )
- \ Gets dimension coordinates of host machine's display.
- $ 904 @ @ 116 - \ **** warning - low mem global ref'd
- dup @ unpack
- rot 4+ @ unpack ;
-
-
- : CHKKEY
- cr type# 189 \ "paused - <space> to continue..."
- cr \ 01Feb94 DBH Add cr. Better for TW.
- (key) cr 0 -> out bl = nif cr decimal abort then ;
-
-
- : ?P
- sleepticks 0 -> sleepticks
- ?terminal
- swap -> sleepticks
- NIF pause EXIT THEN \ No key hit - just do default PAUSE
- (key) drop chkKey ;
-
- : P
- sleepticks 0 -> sleepticks
- ?terminal drop
- -> sleepticks ;
-
- ' p -> pause \ This will be improved when Events is loaded
- ' ?p -> ?pause
-
-
- : WORDS { \ svbase svcurs n -- }
- setToTop: theMark 0 -> out 0 -> n
- base -> svbase hex curs -> svcurs -curs cr
- BEGIN
- next: theMark
- ?dup
- WHILE
- 1 ++> n
- out 60 >
- if cr 0 -> out ?pause then
- link> dup 6 .r 2 spaces .id space
- 20 out 20 mod - spaces
- REPEAT
- svbase -> base
- cr ." No of words: " n . cr
- svcurs -> curs ;
-
-
- false value ENDTRAV? \ May be set from within a trav handler
- \ to terminate the trav
-
- : (TRAV) { theWord parm -- }
- false -> endTrav?
- BEGIN
- next: theMark
- ?dup 0EXIT
- link> parm theWord execute
- endTrav?
- UNTIL ;
-
- : TRAV \ ( xt parm -- )
- \ Traverses the dictionary, passing each xt and the parm
- \ to the passed-in proc.
-
- setToTop: theMark (trav) ;
-
- : TRAV-FROM \ ( xt parm addr -- )
- \ As for TRAV, but starts from the first word whose lfa is
- \ below or at the given address.
-
- set: theMark (trav) ;
-
-
- \ =============== Dump ==================
-
- \ This used to be in the Util module. But sometimes the loading of that
- \ module could cause the address of what we wanted to dump to change.
-
- 0 value DADDR
- 0 value DLEN
-
- : U.R
- >r 0 <# #s #> r> over - spaces type ;
-
- : dot4 0 <# # # # # #> type space ;
-
- : D.4 ( addr len -- ) bounds do i w@ dot4 2 +loop ;
-
- : EMIT. \ ( c -- )
- 127 and bl 126 within? nif drop & . then emit ;
-
- : DLN \ ( addr -- )
- cr dup 8 u.r 2 spaces
- dup ( addr ) 8 2dup d.4 space + 8 d.4 space
- 16 bounds DO i c@ emit. LOOP ;
-
-
- : ?.N \ ( n1 n2 -- n1 )
- 2dup = if ." \/" drop else 1 .r space then ;
-
- : ?.A \ ( n1 n2 -- n1 )
- 2dup = if drop & V emit else 1 .r then ;
-
- : .HEAD \ ( addr len -- addr' len' )
- swap dup -16 and swap 15 and cr 10 spaces
- 8 0 DO i ?.n i 1+ ?.n space 2 +LOOP space
- 16 8 DO i ?.n i 1+ ?.n space 2 +LOOP space
- 16 0 DO i ?.a LOOP rot + ;
-
- :f DUMP { addr len \ svBase svCurs -- }
- base -> svBase hex curs -> svCurs -curs
- addr len .head
- 2dup -> dLen -> dAddr \ Save for DN
- bounds DO i dln ?pause 16 +LOOP cr
- svbase -> base svCurs -> curs ;f
-
- : DN \ Dump next
- dLen ++> dAddr dAddr dLen dump ;
-
- : .W ' >name 200 dump ;
-
-
- <" String
-
- \ Testing:
-
- +echo
-
- :class VArr super{ var obj_array }
- ;class
-
- 6 varr OA
-
- handleList HL
-
- key!
-
- : h1 ." hello" ;
- : h2 ." hi there!" ;
-
- 3 x-array xx
- xts{ h1 h2 h1 } put: xx
-